package com.difsonapps.contacttranslator.dao;

import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.difsonapps.contacttranslator.dto.ContactDTO;

@Repository
@Transactional
public class ContactDAO {
	@Autowired
	protected SessionFactory sessionFactory;

	@Transactional
	public void insert(ContactDTO contactDTO) {
		sessionFactory.getCurrentSession().save(contactDTO);
	}

	@Transactional
	public void update(ContactDTO contactDTO) {
		sessionFactory.getCurrentSession().update(contactDTO);
	}

	@Transactional
	public ContactDTO get(int id) {

		ContactDTO contactDTO = (ContactDTO) sessionFactory.getCurrentSession().get(
				ContactDTO.class, id);
		return contactDTO;
	}

	@SuppressWarnings("unchecked")
	@Transactional
	public List<ContactDTO> getAll() {
		return (List<ContactDTO>) sessionFactory.getCurrentSession()
				.createQuery("Select t from ContactDTO t").list();
	}

	@Transactional(propagation= Propagation.REQUIRES_NEW)
	@SuppressWarnings("unchecked")
	public ContactDTO getByContactIdDeviceId(String contactid,String deviceid) {

		ContactDTO contact = (ContactDTO)sessionFactory
				.getCurrentSession()
				.createQuery("Select r from ContactDTO r where r.contactId=:contactid and r.deviceId=:deviceid")
				.setParameter("contactid", contactid)
				.setParameter("deviceid", deviceid).uniqueResult();
		if(contact != null){
			Hibernate.initialize(contact.getEmailDTOs());
			Hibernate.initialize(contact.getNumberDTOs());
			Hibernate.initialize(contact.getSocialContactDTOs());
		}

		return contact;
	}

	@Transactional
	@SuppressWarnings("unchecked")
	public List<ContactDTO> getByUserEmail(String email) {

		List<ContactDTO> contacts = sessionFactory
				.getCurrentSession()
				.createQuery("Select r from ContactDTO r where r.user.email=:email")
				.setParameter("email", email).list();

		return contacts;
	}

	@Transactional
	public void delete(ContactDTO contactDTO) {
		sessionFactory.getCurrentSession().delete(contactDTO);
	}

	@Transactional
	@SuppressWarnings("unchecked")
	public List<ContactDTO> getByNumberAndEmail(String contactid, String deviceid, String email, String[] listOffNumber  , String[] listOffEmails ) {


		String QUERY = "select distinct c from ContactDTO c, NumberDTO n, EmailDTO e where c.user.email=:email and c.id=n.contactDTO.id  and  c.id=e.contactDTO.id and n.value in (:numbers)  and e.value in (:emails) and c.contactId=:contactid and c.deviceId=:deviceid";
		if(listOffEmails.length == 0)
			QUERY = "select distinct c from ContactDTO c, NumberDTO n where c.user.email=:email and c.id=n.contactDTO.id   and n.value in (:numbers) and c.contactId=:contactid and c.deviceId=:deviceid ";
		if(listOffNumber.length == 0)
			QUERY = "select distinct c from ContactDTO c,  EmailDTO e where c.user.email=:email and  c.id=e.contactDTO.id and  e.value in (:emails) and c.contactId=:contactid and c.deviceId=:deviceid";
		Session currentSession = sessionFactory.getCurrentSession();
		Query requete = currentSession.createQuery(QUERY);
		requete.setParameter("email", email);
		requete.setParameter("contactid", contactid);
		requete.setParameter("deviceid", deviceid);
		if(listOffEmails.length == 0)
			requete.setParameterList("numbers", listOffNumber);
		else if(listOffNumber.length == 0)
			requete.setParameterList("emails", listOffEmails);
		else{
			requete.setParameterList("numbers", listOffNumber)
			.setParameterList("emails", listOffEmails);
		}
		

		List<ContactDTO> contacts = requete.list();
		for (ContactDTO contactDTO2 : contacts) {
			Hibernate.initialize(contactDTO2.getEmailDTOs());
			Hibernate.initialize(contactDTO2.getNumberDTOs());
			Hibernate.initialize(contactDTO2.getSocialContactDTOs());
		}			
		return contacts;
	}

}
